package top.maof.book.rank.book;

import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;
import top.maof.book.aspect.HotAspect;
import top.maof.book.model.Book;
import top.maof.book.rank.*;
import top.maof.book.service.BookService;
import top.maof.book.type.HotType;
import top.maof.book.vo.PageVo;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Set;

// 书热度年榜单处理器
@Component
@Data
@Deprecated
public class BookYearHandle implements Handle<Book>, Rank<Book, BookYearHandle.BookYearPage> {

    @Autowired
    private ZSetOperations zSetOperations;

    @Autowired
    private BookService bookService;

    private static String PREFIX_KEY = "rank:book:year";

    // 书热度年榜单的类型
    private HotType hotType;


    @Override
    public void add(Book book, HandleChain handleChain) {
        Calendar calendar = Calendar.getInstance();

        zSetOperations.incrementScore(HandleChain.generateKey(PREFIX_KEY, hotType.getValue(),
                String.valueOf(calendar.get(Calendar.YEAR))),
                book.getId(), 1);

        handleChain.add(book, handleChain);
    }

    @Override
    public void sub(Book book, HandleChain handleChain) {
        Calendar calendar = Calendar.getInstance();

        zSetOperations.incrementScore(HandleChain.generateKey(PREFIX_KEY, hotType.getValue(),
                String.valueOf(calendar.get(Calendar.YEAR))),
                book.getId(), -1);

        handleChain.sub(book, handleChain);
    }

    @Override
    public PageVo<RankVo<Book>> page(BookYearPage page) {
        String key = HandleChain.generateKey(PREFIX_KEY, hotType.getValue(), String.valueOf(page.getYear()));
        Set<ZSetOperations.TypedTuple<Integer>> set = null;
        if (page.getIsAsc()) {
            set = zSetOperations.rangeWithScores(key, (page.getPage() - 1) * page.getPageSize(),
                    page.getPage() * page.getPageSize() - 1);
        } else {
            set = zSetOperations.reverseRangeWithScores(key, (page.getPage() - 1) * page.getPageSize(),
                    page.getPage() * page.getPageSize() - 1);
        }
        List<RankVo<Book>> list = new ArrayList<>(set.size());
        set.forEach(tuple -> {
            Integer bookId = tuple.getValue();
            RankVo rankVO = new RankVo();
            rankVO.setScore(tuple.getScore());
            rankVO.setT(bookService.find(bookId));
            list.add(rankVO);
        });
        Long size = zSetOperations.size(key);
        PageVo pageVo = new PageVo();
        pageVo.setCount(size);
        pageVo.setList(list);
        return pageVo;
    }

    @Data
    public static class BookYearPage extends Page {
        private Integer year;
    }

}
